/**
 * 
 */
package org.springframework.data.redis.test;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

/** 
* @version:v1.0
* @Description: 
* @author: jzhao
* @date: 2019年11月20日下午4:50:24
*/

public class MapMain {
    private static final int COUNT = 1000000;

    public static void main(String[] args) {
    	
    	testGet();
    	
    	if(1== 1)
    		return;
    	
        System.out.println("starting ...");
        long start = System.currentTimeMillis();
        for (int i = 0; i < COUNT; i++) {
            ClassA clzA = new ClassA();
            clzA.setName("A" + i);
            clzA.setAge(i);
            clzA.setAddress("西安市雁塔区");
            clzA.addProjectExperience("持续集成产品", "agent开发");
            clzA.addProjectExperience("持续部署产品", "引擎开发");
            clzA.addProjectExperience("云平台", "新的平台规划主要功能开发");
        }
        long end = System.currentTimeMillis();
        long diff = end - start;
        System.out.println("native call:" + diff);

        try {
            long start2 = System.currentTimeMillis();
            for (int i = 0; i < COUNT; i++) {
                Class clzA = Class.forName("org.springframework.data.redis.test.ClassA");
                Class<?>[] argsType = new Class[1];
                argsType[0] = String.class;

                Class<?>[] argsTypeInt = new Class[1];
                argsTypeInt[0] = Integer.class;

                Class<?>[] argsTypeMap = new Class[2];
                argsTypeMap[0] = String.class;
                argsTypeMap[1] = String.class;

                Method setName = clzA.getMethod("setName", argsType);
                Method setAge = clzA.getMethod("setAge", argsTypeInt);
                Method setAddress = clzA.getMethod("setAddress", argsType);
                Method addProjectExperience = clzA.getMethod("addProjectExperience", argsTypeMap);

                Object obj = clzA.newInstance();
                setName.invoke(obj, "A" + i);
                setAge.invoke(obj,  i);
                setAddress.invoke(obj, "西安市雁塔区");
                addProjectExperience.invoke(obj, "持续集成产品", "agent开发");
                addProjectExperience.invoke(obj, "持续部署产品", "引擎开发");
                addProjectExperience.invoke(obj, "云平台", "新的平台规划主要功能开发");
            }
            long end2 = System.currentTimeMillis();
            long diff2 = end2 - start2;
            System.out.println("reflect call:" + diff2);
        } catch (Exception ex) {
            ex.printStackTrace();
        }


        try {
            long start3 = System.currentTimeMillis();

            Class clzA = Class.forName("org.springframework.data.redis.test.ClassA");
            Class<?>[] argsType = new Class[1];
            argsType[0] = String.class;

            Class<?>[] argsTypeInt = new Class[1];
            argsTypeInt[0] = Integer.class;

            Class<?>[] argsTypeMap = new Class[2];
            argsTypeMap[0] = String.class;
            argsTypeMap[1] = String.class;

            Method setName = clzA.getMethod("setName", argsType);
            Method setAge = clzA.getMethod("setAge", argsTypeInt);
            Method setAddress = clzA.getMethod("setAddress", argsType);
            Method addProjectExperience = clzA.getMethod("addProjectExperience", argsTypeMap);

            for (int i = 0; i < COUNT; i++) {
                Object obj = clzA.newInstance();
                setName.invoke(obj, "A" + i);
                setAge.invoke(obj,  i);
                setAddress.invoke(obj, "西安市雁塔区");
                addProjectExperience.invoke(obj, "持续集成产品", "agent开发");
                addProjectExperience.invoke(obj, "持续部署产品", "引擎开发");
                addProjectExperience.invoke(obj, "云平台", "新的平台规划主要功能开发");
            }
            long end3 = System.currentTimeMillis();
            long diff3 = end3 - start3;
            System.out.println("cache call:" + diff3);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
    
    
    public static void testGet() {
    	 ClassA clzA = new ClassA();
    	 clzA.setId(1558l);
         clzA.setName("A1");
         clzA.setAge(12);
         clzA.setAddress("西安市雁塔区");
         clzA.addProjectExperience("持续集成产品", "agent开发");
         clzA.addProjectExperience("持续部署产品", "引擎开发");
         clzA.addProjectExperience("云平台", "新的平台规划主要功能开发");
         
         long start = System.currentTimeMillis();
         for (int i = 0; i < COUNT; i++) {
        	 clzA.getId();
         }
         long end = System.currentTimeMillis();
         long diff = end - start;
         System.out.println("native call:" + diff);
         
         
         try {
             long start2 = System.currentTimeMillis();
             for (int i = 0; i < COUNT; i++) {
                 Class clazz = clzA.getClass();
                 
                

        		 Field[] fs = org.apache.commons.lang3.reflect.FieldUtils.getAllFields(clazz);

                 String idName = null;
        		 Object idValue = null;
                for ( Field f: fs ) {
                    // 只有被 @Id 标注过的方法才进行测试
                    if ( f.isAnnotationPresent( javax.persistence.Id.class )) {
                   	 f.setAccessible(true); 
                   	idName = f.getName();
                       try {
        					idValue = f.get(clzA);
        				} catch (Exception e) {
        					// TODO Auto-generated catch block
        					e.printStackTrace();
        				} 
                    }
                }
             }
             long end2 = System.currentTimeMillis();
             long diff2 = end2 - start2;
             System.out.println("reflect call:" + diff2);
         } catch (Exception ex) {
             ex.printStackTrace();
         }


         try {
             

             Class clazz = clzA.getClass();
             //clazz.getName() //org.springframework.data.redis.test.ClassA
    		 Field[] fs = org.apache.commons.lang3.reflect.FieldUtils.getAllFields(clazz);
    		 
    		 Field target = null;
    		 for ( Field f: fs ) {
	                if ( f.isAnnotationPresent( javax.persistence.Id.class )) {
	               	 f.setAccessible(true); 
	               	target = f;
                }
    		 }
    		 
    		 String idName = null;
    		 Object idValue = null;
    		 
    		 long start3 = System.currentTimeMillis();
    		 for (int i = 0; i < COUNT; i++) {
	    		 
//		            for ( Field f: fs ) {
		                // 只有被 @Id 标注过的方法才进行测试
//		                if ( f.isAnnotationPresent( javax.persistence.Id.class )) {
//		               	 f.setAccessible(true); 
//		               	idName = f.getName();
//		                   try {
//		    					idValue = f.get(clzA);
//		    				} catch (Exception e) {
//		    					// TODO Auto-generated catch block
//		    					e.printStackTrace();
//		    				} 
//		                }
		            	

				               	idName = target.getName();
				                   try {
				    					idValue = target.get(clzA);
				    				} catch (Exception e) {
				    					// TODO Auto-generated catch block
				    					e.printStackTrace();
				    				} 
				                
//		            }
    		 }
             long end3 = System.currentTimeMillis();
             long diff3 = end3 - start3;
             System.out.println(idName+":"+idValue+":cache call:" + diff3);
         } catch (Exception ex) {
             ex.printStackTrace();
         }
    }
}
